/*
 * Semaphore Demo
 * Liu Jinzhu
 * 2018-04-09
 */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>

void *thread_function(void *arg);
pthread_mutex_t work_mutex;			// 定义互斥量

#define 	WORK_SIZE 1024
char 		work_area[WORK_SIZE];
int 		time_to_exit = 1;

int main() {

    int res;                			// 保存线程创建返回值
    pthread_t a_thread;    			// 保存线程标识信息
    void *thread_result;   	 		// 线程运行返回值

    res = pthread_mutex_init(&work_mutex, NULL); // 创建并初始化互斥量

    if (0 != res) {
    		perror("初始化互斥量失败\n");
    		exit(EXIT_FAILURE);
     }
    res = pthread_create(&a_thread, NULL, thread_function, NULL);
    if (0 != res) {
        perror("线程创建失败\n");
        exit(EXIT_FAILURE);
     }

    printf("主线程加锁(0)\n");
    pthread_mutex_lock(&work_mutex);

    printf("请输入要传送的信息,输入'End'退出\n");
    while(time_to_exit) {
    	fgets(work_area, WORK_SIZE, stdin);
    	printf("主线程尝试解锁(1)\n");
    	pthread_mutex_unlock(&work_mutex);
    	while (1) {
    		printf("主线程加锁(2)\n");
    		pthread_mutex_lock(&work_mutex);
    		if (work_area[0] != '\0') {
    			printf("主线程尝试解锁(2)\n");
    			pthread_mutex_unlock(&work_mutex);
    			printf("主线程休眠1秒\n");
    			sleep(1);
    		} else {
    			break;
    		}
    	}
    }

    printf("主线程解锁(0)\n");
    pthread_mutex_unlock(&work_mutex);
    printf("等待线程结束...\n");
    res = pthread_join(a_thread, &thread_result);
    if (0 != res) {
        perror("等待线程结束失败\n");
        exit(EXIT_FAILURE);
    }
    printf("线程已结束\n");
    pthread_mutex_destroy(&work_mutex);

    exit(EXIT_SUCCESS);

}

void *thread_function(void *arg) {
	printf("子线程休眠1秒(0)\n");
	sleep(1);
	printf("子线程尝试加锁(0)\n");
	pthread_mutex_lock(&work_mutex);

	while(strncmp("end", work_area, 3) != 0) {	// 判断输入是否为end
		printf("收到%d个字符\n", (int)(strlen(work_area) - 1));
		work_area[0] = '\0';

		printf("子线程解锁(1)\n");
		pthread_mutex_unlock(&work_mutex);
		printf("子线程休眠1秒(1)\n");
		sleep(1);
		printf("子线程尝试加锁(1)\n");
		pthread_mutex_lock(&work_mutex);

		while(work_area[0] == '\0') {
			printf("子线程解锁(2)\n");
			pthread_mutex_unlock(&work_mutex);
			printf("子线程休眠1秒(2)\n");
			sleep(1);
			printf("子线程尝试加锁(2)\n");
			pthread_mutex_lock(&work_mutex);
		}
	}

	time_to_exit = 0;
	work_area[0] = '\0';
	printf("子线程解锁(0)\n");
	pthread_mutex_unlock(&work_mutex);
   pthread_exit(0);

}
